package com.hedl.practice.diyJava.multithreading.thread_pool.completable_future.test;

import java.util.concurrent.CompletableFuture;

public class StudyCompletableFuture_1 {
    /**
     * 在 main() 方法中创建一个 CompletableFuture 对象 cf，用于执行异步任务。
     * 使用 supplyAsync() 方法创建一个异步任务，它的执行体是 fetchPrice() 方法。fetchPrice() 方法会模拟获取商品价格的过程，并返回一个随机的商品价格。
     * 使用 thenAccept() 方法注册一个回调函数，用于在异步任务执行成功时打印商品价格。这个回调函数接收一个 Consumer 类型的参数，即异步任务的执行结果。
     * 使用 exceptionally() 方法注册一个异常回调函数，用于在异步任务执行异常时打印异常信息。这个异常回调函数接收一个 Function 类型的参数，即异步任务的执行异常。
     * 使用 Thread.sleep() 方法阻塞主线程 200 毫秒，避免 CompletableFuture 默认使用的线程池立刻关闭。
     * 异步任务在另一个线程中执行，如果执行成功，则会调用 thenAccept() 方法注册的回调函数，打印商品价格；如果执行异常，则会调用 exceptionally() 方法注册的异常回调函数，打印异常信息。
     * 如果异步任务执行成功，主线程会阻塞 200 毫秒后结束；如果异步任务执行异常，主线程会立刻结束。
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        //创建一步执行任务
        CompletableFuture<Double> cf = CompletableFuture.supplyAsync(StudyCompletableFuture_1::fetchPrice);//第一步：调用fetchPrice()方法
        //如果执行成功
        cf.thenAccept((result)->{
            System.out.println("price:"+result);
        });

        //如果执行异常
        cf.exceptionally((e)->{ //直接调用异常
            e.printStackTrace();
            return null;
        });

        //主线程不要立刻结束，否则CompletableFuture默认使用的线程池会立刻关闭
        Thread.sleep(200);
    }


    static Double fetchPrice(){
        try{
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }
        if (Math.random() < 0.3){       //判断是小于0.3；如果为true抛出一场
            throw new RuntimeException("fetch price failed!");
        }
        //System.out.println(5+Math.random() * 5);
        return 5+Math.random() * 5;
    }
}
